package pcgen.android.app;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.HashMap;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;

import android.app.Activity;
import android.app.Application;
import android.content.Context;

import pcgen.android.Logger;

public abstract class ApplicationEx extends Application 
{
	public void exit(Activity activity, String message)
	{
		try
    	{
    		AppUtils.exit(activity, message);
    	}
    	catch (Throwable tr)
    	{
    		Logger.e(TAG, "exit", tr);
    	}
	}
	
	public synchronized Context getActiveContext(String className) 
	{
		Validate.notEmpty(className);
    	
		WeakReference<Context> ref = null;
		
    	try
    	{
    	    ref = _contextObjects.get(className);
    	    if (ref == null)
    	        return null;
    	}
    	catch (Throwable tr)
    	{
    		Logger.e(TAG, "getActiveContext", tr);
    	}

	    return ref.get();
	}
	
	public File getExternalStorageDirectory()
	{
		try
		{
			File external = android.os.Environment.getExternalStorageDirectory();
			boolean canWrite = external.canWrite();
			
			if (!external.exists())
			{
				if (canWrite)
					external.mkdir();
			}
			
			return external;
		}
		catch (Throwable tr)
		{
			Logger.e(TAG, "getExternalStorageDirectory", tr);
		}
		
		return null;
	}
	
	public File getExternalStorageDirectoryApplication()
	{
		try
		{
			File external = android.os.Environment.getExternalStorageDirectory();
			boolean canWrite = external.canWrite();

			String appDirectoryName = initializeExternalStorageDirectoryName();
			if (!StringUtils.isEmpty(appDirectoryName))
				external = new File(external, appDirectoryName);
			
			if (!external.exists())
			{
				if (canWrite)
					external.mkdir();
			}
			
			return external;
		}
		catch (Throwable tr)
		{
			Logger.e(TAG, "getExternalStorageDirectoryApplication", tr);
		}
		
		return null;
	}
	
	public synchronized boolean getApplicationIsForeground()
	{
		return (_foregroundActivity != null);
	}
	
	public synchronized Activity getApplicationIsForegroundActivity()
	{
		return _foregroundActivity;
	}
	
	public synchronized OptionMenusProvider getOptionMenusProvider()
	{
		return _optionMenuProvider;
	}
	
	public synchronized void setApplicationIsForeground(Activity activity)
	{
		_foregroundActivity = activity;
	}
	
	public synchronized void setOptionMenusProvider(OptionMenusProvider provider)
	{
		_optionMenuProvider = provider;
	}
	
	public abstract String initializeExternalStorageDirectoryName();
	
	public synchronized void removeApplicationIsForeground() 
	{
	    _foregroundActivity = null;
	}
	
	public synchronized void resetActiveContext(String className) 
	{
	    Validate.notEmpty(className);
    	
    	try
    	{
    		_contextObjects.remove(className);
    	}
    	catch (Throwable tr)
    	{
    		Logger.e(TAG, "resetActiveContext", tr);
    	}
	}
	
	public synchronized void setActiveContext(String className, Context context) 
	{
	    Validate.notEmpty(className);
	    Validate.notNull(context);
    	
    	try
    	{
    		WeakReference<Context> ref = new WeakReference<Context>(context);
    		_contextObjects.put(className, ref);
    	}
    	catch (Throwable tr)
    	{
    		Logger.e(TAG, "setActiveContext", tr);
    	}
	}

	private Activity _foregroundActivity;
	private OptionMenusProvider _optionMenuProvider;
	private HashMap<String, WeakReference<Context>> _contextObjects = new HashMap<String, WeakReference<Context>>();

	private static final String TAG = ApplicationEx.class.getSimpleName();
}
